// CSV处理服务 - 用于保存和读取链结构
export interface ChainStructure {
  nodes: Array<{
    id: number
    name: string
    backends: number
    frontendIp?: string
    backendIps?: string[]
    level?: number
    x?: number
    y?: number
  }>
  connections: Array<{
    from: { nodeId: number | 'target'; kind: 'frontend' | 'backend' | 'target'; backendIndex?: number }
    to: { nodeId: number | 'target'; kind: 'frontend' | 'backend' | 'target'; backendIndex?: number }
  }>
  attackTarget?: {
    ip: string
    port: number
    x?: number
    y?: number
  }
}

// 新的三元组格式接口
export interface TripleStructure {
  parent_drs_in_ip: string
  parent_drs_backend_ip: string | string[]  // 支持单个后端IP或多个后端IP数组
  child_drs_in_ips: string | string[]       // 支持单个子节点IP或多个子节点IP数组
}

class CsvService {
  /**
   * 导出三元组结构为CSV文件
   * @param tripleStructures 三元组数据数组
   * @param filename 文件名（可选）
   */
  exportTripleStructure(tripleStructures: TripleStructure[], filename?: string): void {
    try {
      const csvContent = this.generateTripleCsvContent(tripleStructures)
      const defaultFilename = `attack_chain_${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.csv`
      const finalFilename = filename || defaultFilename
      
      // 创建Blob对象
      const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
      
      // 创建下载链接
      const link = document.createElement('a')
      if (link.download !== undefined) {
        const url = URL.createObjectURL(blob)
        link.setAttribute('href', url)
        link.setAttribute('download', finalFilename)
        link.style.visibility = 'hidden'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        URL.revokeObjectURL(url)
      }
      
      console.log('三元组结构已导出为CSV文件:', finalFilename)
    } catch (error) {
      console.error('导出CSV文件失败:', error)
      throw new Error(`导出失败: ${error instanceof Error ? error.message : '未知错误'}`)
    }
  }

  /**
   * 从CSV文件导入三元组结构
   * @param file CSV文件
   * @returns Promise<TripleStructure[]>
   */
  async importTripleStructure(file: File): Promise<TripleStructure[]> {
    try {
      const text = await this.readFileAsText(file)
      const tripleStructures = this.parseTripleCsvContent(text)
      console.log('三元组结构已从CSV文件导入:', file.name)
      return tripleStructures
    } catch (error) {
      console.error('导入CSV文件失败:', error)
      throw new Error(`导入失败: ${error instanceof Error ? error.message : '未知错误'}`)
    }
  }

  /**
   * 导出链结构为CSV文件
   * @param chainStructure 链结构数据
   * @param filename 文件名（可选）
   */
  exportChainStructure(chainStructure: ChainStructure, filename?: string): void {
    try {
      const csvContent = this.generateCsvContent(chainStructure)
      const defaultFilename = `chain_structure_${new Date().toISOString().slice(0, 19).replace(/:/g, '-')}.csv`
      const finalFilename = filename || defaultFilename
      
      // 创建Blob对象
      const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' })
      
      // 创建下载链接
      const link = document.createElement('a')
      if (link.download !== undefined) {
        const url = URL.createObjectURL(blob)
        link.setAttribute('href', url)
        link.setAttribute('download', finalFilename)
        link.style.visibility = 'hidden'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        URL.revokeObjectURL(url)
      }
      
      console.log('链结构已导出为CSV文件:', finalFilename)
    } catch (error) {
      console.error('导出CSV文件失败:', error)
      throw new Error(`导出失败: ${error instanceof Error ? error.message : '未知错误'}`)
    }
  }

  /**
   * 从CSV文件导入链结构
   * @param file CSV文件
   * @returns Promise<ChainStructure>
   */
  async importChainStructure(file: File): Promise<ChainStructure> {
    try {
      const text = await this.readFileAsText(file)
      const chainStructure = this.parseCsvContent(text)
      console.log('链结构已从CSV文件导入:', file.name)
      return chainStructure
    } catch (error) {
      console.error('导入CSV文件失败:', error)
      throw new Error(`导入失败: ${error instanceof Error ? error.message : '未知错误'}`)
    }
  }

  /**
   * 生成三元组CSV内容
   * @param tripleStructures 三元组数据数组
   * @returns CSV字符串
   */
  private generateTripleCsvContent(tripleStructures: TripleStructure[]): string {
    const csvRows: string[] = []
    
    // CSV头部
    csvRows.push('parent_drs_in_ip,parent_drs_backend_ip,child_drs_in_ips')
    
    // 三元组数据
    tripleStructures.forEach(triple => {
      const childIpsStr = triple.child_drs_in_ips.join(',')
      const row = [
        triple.parent_drs_in_ip,
        triple.parent_drs_backend_ip,
        `"${childIpsStr}"`
      ].join(',')
      csvRows.push(row)
    })
    
    return csvRows.join('\n')
  }

  /**
   * 解析三元组CSV内容
   * @param csvContent CSV字符串
   * @returns TripleStructure[]
   */
  parseTripleCsvContent(csvContent: string): TripleStructure[] {
    const lines = csvContent.split('\n').map(line => line.trim()).filter(line => line && !line.startsWith('#'))
    const tripleStructures: TripleStructure[] = []
    
    // 跳过头部行
    const dataLines = lines.slice(1)
    
    for (const line of dataLines) {
      const columns = this.parseCsvRow(line)
      if (columns.length >= 3) {
        // 解析后端IP（可能包含多个，逗号分隔）
        const backendIps = columns[1] ? columns[1].split(',').map(ip => ip.trim()).filter(ip => ip) : []
        
        // 解析子节点IP（可能包含多个，逗号分隔）
        const childIps = columns[2] ? columns[2].split(',').map(ip => ip.trim()).filter(ip => ip) : []
        
        tripleStructures.push({
          parent_drs_in_ip: columns[0].trim(),
          parent_drs_backend_ip: backendIps.length === 1 ? backendIps[0] : backendIps,
          child_drs_in_ips: childIps.length === 1 ? childIps[0] : childIps
        })
      }
    }
    
    return tripleStructures
  }

  /**
   * 生成CSV内容
   * @param chainStructure 链结构数据
   * @returns CSV字符串
   */
  private generateCsvContent(chainStructure: ChainStructure): string {
    const csvRows: string[] = []
    
    // CSV头部
    csvRows.push('# DNS链式攻击拓扑结构')
    csvRows.push('# 格式: type,id,name,backends,frontendIp,backendIps,level,x,y')
    csvRows.push('')
    
    // 节点数据
    csvRows.push('[NODES]')
    csvRows.push('type,id,name,backends,frontendIp,backendIps,level,x,y')
    
    chainStructure.nodes.forEach(node => {
      const backendIpsStr = node.backendIps ? node.backendIps.join(';') : ''
      const row = [
        'node',
        node.id.toString(),
        `"${node.name}"`,
        node.backends.toString(),
        node.frontendIp || '',
        `"${backendIpsStr}"`,
        (node.level || 1).toString(),
        (node.x || 0).toString(),
        (node.y || 0).toString()
      ].join(',')
      csvRows.push(row)
    })
    
    // 连接数据
    csvRows.push('')
    csvRows.push('[CONNECTIONS]')
    csvRows.push('from_nodeId,from_kind,from_backendIndex,to_nodeId,to_kind,to_backendIndex')
    
    chainStructure.connections.forEach(conn => {
      const fromBackendIndex = conn.from.backendIndex !== undefined ? conn.from.backendIndex.toString() : ''
      const toBackendIndex = conn.to.backendIndex !== undefined ? conn.to.backendIndex.toString() : ''
      const row = [
        conn.from.nodeId.toString(),
        conn.from.kind,
        fromBackendIndex,
        conn.to.nodeId.toString(),
        conn.to.kind,
        toBackendIndex
      ].join(',')
      csvRows.push(row)
    })
    
    // 攻击目标数据
    if (chainStructure.attackTarget) {
      csvRows.push('')
      csvRows.push('[ATTACK_TARGET]')
      csvRows.push('ip,port,x,y')
      const target = chainStructure.attackTarget
      csvRows.push([
        target.ip,
        target.port.toString(),
        (target.x || 0).toString(),
        (target.y || 0).toString()
      ].join(','))
    }
    
    return csvRows.join('\n')
  }

  /**
   * 解析CSV内容
   * @param csvContent CSV字符串
   * @returns ChainStructure
   */
  private parseCsvContent(csvContent: string): ChainStructure {
    const lines = csvContent.split('\n').map(line => line.trim()).filter(line => line && !line.startsWith('#'))
    
    const chainStructure: ChainStructure = {
      nodes: [],
      connections: [],
      attackTarget: undefined
    }
    
    let currentSection = ''
    
    for (const line of lines) {
      if (line === '[NODES]') {
        currentSection = 'nodes'
        continue
      } else if (line === '[CONNECTIONS]') {
        currentSection = 'connections'
        continue
      } else if (line === '[ATTACK_TARGET]') {
        currentSection = 'attackTarget'
        continue
      }
      
      // 跳过头部行
      if (line.includes('type,id,name') || line.includes('from_nodeId') || line.includes('ip,port')) {
        continue
      }
      
      const columns = this.parseCsvRow(line)
      
      switch (currentSection) {
        case 'nodes':
          if (columns.length >= 9) {
            const backendIps = columns[5] ? columns[5].split(';').filter(ip => ip.trim()) : []
            chainStructure.nodes.push({
              id: parseInt(columns[1]),
              name: columns[2],
              backends: parseInt(columns[3]),
              frontendIp: columns[4] || undefined,
              backendIps: backendIps.length > 0 ? backendIps : undefined,
              level: parseInt(columns[6]) || 1,
              x: parseInt(columns[7]) || 0,
              y: parseInt(columns[8]) || 0
            })
          }
          break
          
        case 'connections':
          if (columns.length >= 6) {
            chainStructure.connections.push({
              from: {
                nodeId: columns[0] === 'target' ? 'target' : parseInt(columns[0]),
                kind: columns[1] as 'frontend' | 'backend' | 'target',
                backendIndex: columns[2] ? parseInt(columns[2]) : undefined
              },
              to: {
                nodeId: columns[3] === 'target' ? 'target' : parseInt(columns[3]),
                kind: columns[4] as 'frontend' | 'backend' | 'target',
                backendIndex: columns[5] ? parseInt(columns[5]) : undefined
              }
            })
          }
          break
          
        case 'attackTarget':
          if (columns.length >= 4) {
            chainStructure.attackTarget = {
              ip: columns[0],
              port: parseInt(columns[1]),
              x: parseInt(columns[2]) || 0,
              y: parseInt(columns[3]) || 0
            }
          }
          break
      }
    }
    
    return chainStructure
  }

  /**
   * 解析CSV行
   * @param row CSV行字符串
   * @returns 解析后的列数组
   */
  private parseCsvRow(row: string): string[] {
    const result: string[] = []
    let current = ''
    let inQuotes = false
    
    for (let i = 0; i < row.length; i++) {
      const char = row[i]
      
      if (char === '"') {
        if (inQuotes && row[i + 1] === '"') {
          current += '"'
          i++ // 跳过下一个引号
        } else {
          inQuotes = !inQuotes
        }
      } else if (char === ',' && !inQuotes) {
        result.push(current)
        current = ''
      } else {
        current += char
      }
    }
    
    result.push(current)
    return result
  }

  /**
   * 读取文件为文本
   * @param file 文件对象
   * @returns Promise<string>
   */
  private readFileAsText(file: File): Promise<string> {
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.onload = (e) => {
        resolve(e.target?.result as string || '')
      }
      reader.onerror = () => {
        reject(new Error('文件读取失败'))
      }
      reader.readAsText(file, 'utf-8')
    })
  }

  /**
   * 验证CSV文件格式
   * @param content CSV内容
   * @returns 是否有效
   */
  validateCsvFormat(content: string): boolean {
    try {
      const lines = content.split('\n').map(line => line.trim()).filter(line => line && !line.startsWith('#'))
      
      // 检查是否包含必要的节
      const hasNodes = lines.includes('[NODES]')
      const hasConnections = lines.includes('[CONNECTIONS]')
      
      return hasNodes && hasConnections
    } catch (error) {
      return false
    }
  }
}

// 导出单例实例
export const csvService = new CsvService()









